home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UTIL / FILEUTIL / HIERARCH / !Hierarchy / doc / General < prev    next >
Text File  |  1994-11-19  |  14KB  |  320 lines

  1. ----------------------------------------------------------------------
  2.                              Vorwort
  3. ----------------------------------------------------------------------
  4.  
  5.   Die üblichen Aktionen zum Übertragen von Daten zwischen Programmen
  6. und Dateisystemen sind jedem, der schon einmal mit einem Archimedes
  7. unter RiscOS gearbeitet hat, bekannt. Für den Benutzer der Fenster-
  8. oberfläche WIMP stellt sich daß sehr einfach und intuitiv dar.
  9.  
  10.   Programmierer aus der Amiga-, Macintosh- oder Windows-Szene könnten
  11. jetzt vermuten, daß hinter diesem einfachen Verfahren des Icon-Herum­
  12. schiebens eine ganze Menge Programmierarbeit steckt. Leute, die zum
  13. erstenmal vor einem Archimedes sitzen, kann man jedenfalls immer
  14. daran erkennen, daß sie eine Datei speichern wollen, indem sie die
  15. mittlere Maustaste drücken (und meist gedrückt halten), mit dem Maus-
  16. zeiger auf 'Save' gehen, diesen Menüpunkt dann irgendwie anwählen und
  17. sich wundern, daß kein typischer File-Requester erscheint.
  18.  
  19.   Es ist bei weitem nicht so kompliziert! Ganz im Gegenteil. Die
  20. einzige Voraussetzung, die man erfüllen muß, um nachfolgende Er-
  21. läuterungen zu verstehen, sind Kenntnisse über das Message-System
  22. des WIMP. Man kommt ohnehin nicht drumherum, wenn man eine Multi-
  23. tasking-Applikation unter RiscOS entwickeln will.
  24.  
  25. ----------------------------------------------------------------------
  26.                      Das Data Transfer Protocol   
  27. ----------------------------------------------------------------------
  28.  
  29.   Aus Programmierersicht läßt sich der Vorgang der Übertragung
  30. von Daten zwischen Applikationen noch einfacher verstehen. Ein
  31. wesentlicher Unterschied von RiscOS zu anderen Betriebssystem ist
  32. schon einmal die Tatsache, daß alle Dateisysteme unter RiscOS auch
  33. nichts anderes als (Module)-Tasks sind. Den krassesten Gegensatz zu
  34. diesem Konzept bildet wohl ein IBM-kompatibler PC, auf dem MS-DOS
  35. läuft.
  36.  
  37.   Für einen Archimedes-Programmierer bedeutet es jedenfalls, daß
  38. er Sonderfälle ausschließen kann: es macht keinen Unterschied,
  39. Daten auf Festplatte zu schreiben oder z.B. einem DTP-System
  40. zu übergeben. Zu diesem Zweck wurde ein Message-Protokoll ent-
  41. worfen, an das sich auch die Dateisysteme halten. Dadurch verrin-
  42. gert sich der Code-Overhead eines Programms zur Datenübertragung
  43. erheblich. Dieses Protokoll kommt mit 7 standardisierten Message-
  44. Strukturen aus:
  45.  
  46.   Message_DataSave          1
  47.   Message_DataSaveAck        2
  48.   Message_DataLoad        3
  49.   Message_DataLoadAck        4
  50.   Message_DataOpen        5
  51.   Message_RamFetch        6
  52.   Message_RamTransmit        7
  53.  
  54. Die Struktur dieser Messages wird in den beiliegenden Dateien
  55. genauer beschrieben. Diese Datei beschreibt bloß die generellen
  56. Vorgänge und kann als Kurs für Einsteiger angesehen werden.
  57.  
  58.   Wird vom Benutzer eines Programms jetzt eine 'Speicheraktion'
  59. ausgelöst, werden einige (oder alle) Message-Strukturen in einer
  60. festgelegten Reihenfolge zwischen den beteiligten Tasks ver-
  61. sandt. Leider wird der von Acorn definierte Standard nicht in
  62. jedem Fall eingehalten.
  63.  
  64.   1. Das Sichern von Daten in eine Datei.
  65.   ---------------------------------------
  66.      Ausgelöst wird diese Aktion durch den üblichen 'Save as:'-
  67.      Dialog eines Programms. Dieser Dialog enthält mindestens
  68.      ein Texticon, in das man den Endnamen der zu erzeugenden
  69.      Datei schreiben kann sowie ein Icon, das auch den jeweiligen
  70.      Typ der Datei anzeigen sollte.
  71.      Folgendes geschieht:
  72.  
  73.      - Der Benutzer hat das Icon in ein Verzeichnisfenster
  74.        gezogen und 'läßt es los'. Das Programm empfängt
  75.        beim nächsten Aufruf von Wimp_Poll als Rückgabewert
  76.        User_Drag_Box.
  77.  
  78.      - Das Programm ruft Wimp_GetPointerInfo auf. Es erhält
  79.        folgende Informationen: absolute Koordinaten des
  80.        Mauszeigers, Zustand der Maustasten sowie die Handle
  81.        des Icons bzw. Fensters, in denen der Mauszeiger sich
  82.        gerade befindet.
  83.        
  84.      - Das Programm schickt Message_DataSave an den Filer,
  85.        indem es die vorher ermittelten Informationen benutzt.
  86.        Weiterhin übergeben wird der Dateiendname, den der
  87.        Benutzer der Datei gegeben hat.
  88.        
  89.      - Der Filer antwortet mit Message_DataSaveAck. Diese
  90.        Message enthält den kompletten Pfadnamen der zu er-
  91.        zeugenden Datei.
  92.        
  93.      - Das Programm sichert die Daten in diese Datei.
  94.      
  95.      - Das Programm schickt Message_DataLoad an den Filer.
  96.        Diese Message enthält den zuvor übermittelten
  97.        kompletten Pfadnamen der erzeugten Datei.
  98.        
  99.      - Der Filer antwortet mit Message_DataLoadAck.
  100.  
  101.      Wer die letzten beiden Schritte für überflüssig hält,
  102.      sollte sich das folgende Beispiel durchlesen.
  103.  
  104.   2. Das Übertragen von Daten zu einer anderen Applikation.
  105.   ---------------------------------------------------------
  106.      Der 'Save as:'-Dialog findet wieder Anwendung, mit dem
  107.      Unterschied, daß das Icon nicht in einem Verzeichnis-
  108.      fenster, sondern auf dem Iconbar-Icon oder Fenster einer
  109.      anderen Applikation 'abgelegt' wird.
  110.  
  111.      - Wimp_Poll des übertragenden Programms ergibt ein
  112.        Ereignis des Typs User_Drag_Box (siehe oben).
  113.        
  114.      - Das übertragende Programm ruf Wimp_GetPointerInfo auf.
  115.      
  116.      - Das Programm schickt Message_DataSave an das empfangende
  117.        Programm, indem es die vorher ermittelten Informationen
  118.        benutzt.
  119.        
  120.        => Bisher unterscheidet sich also noch nichts vom ersten
  121.           Beispiel. Es ist für die übertragende Applikation
  122.           auch nicht ohne weiteres erkennbar, um was für eine
  123.           Art von Task es sich hier handelt.
  124.  
  125.      - Das empfangende Programm anwortet wie erwartet mit
  126.        Message_DataSaveAck. Diese Message enthält üblicherweise
  127.        den Pfadnamen einer temporären Datei <Wimp$Scrap>.
  128.        
  129.      - Das übertragende Programm sichert die Daten in diese
  130.        temporäre Datei. (Der Filer erweitert die System-
  131.        variable <Wimp$Scrap> zu einem kompletten Pfadnamen.)
  132.        
  133.      - Das übertragende Programm schickt Message_DataLoad an
  134.        das empfangende Programm. Diese Message enthält den
  135.        Pfadnamen aus der empfangenen Message_DataSaveAck,
  136.        also z.B. <Wimp$Scrap>.
  137.        
  138.      - Das empfangende Programm lädt die Daten aus der tempo-
  139.        rären Datei und löscht diese Datei.
  140.        
  141.      - Das empfangende Programm antwortet wie erwartet mit
  142.        Message_DataLoadAck.
  143.        
  144.        => Wie man sieht, braucht ein Programm also gar nicht
  145.           zu 'wissen', mit wem es zu tun hat. Der Vorgang der
  146.           Datenübertragung ist immer der gleiche. Es folgt
  147.           eine Kurzfassung der Vorgänge. Nehmen wir an, A will
  148.           B die Datei C übertragen. D sei der Pfadname der
  149.           temporären oder endgültigen Datei. Der Unterschied
  150.           zwischen C und D ist, daß D nicht nur den gewünschten
  151.           Endnamen der Datei, sondern auch Pfadangaben beinhal-
  152.           tet. Der unter RiscOS 2 übliche Pfadname für D ist
  153.           <Wimp$Scrap> = z.B. 'SCSI::HD0.$.!System.ScrapFile'.
  154.           
  155.           1. A -> B: Message_DataSave C
  156.           2. B -> A: Message_DataSaveAck D
  157.           3.      A: Sichert Daten in D
  158.           4. A -> B: Message_DataLoad D
  159.           5:      B: Lädt die Daten aus D und löscht D
  160.           6: B -> A: Message_DataLoadAck D
  161.  
  162.           Der entscheidende Unterschied, der A verborgen bleibt,
  163.           ist das Verhalten von B nach Schritt 4. Der Filer wird
  164.           Schritt 5 natürlich nicht ausführen, er antwortet aber
  165.           korrekt. Bekommt A auf Message_DataLoad keine Antwort
  166.           der Form DataLoadAck, so hat A die Datei D zu löschen
  167.           und eine Fehlermeldung auszugeben: 'Data transfer
  168.           failed: Receiver died.'
  169.  
  170.  
  171.   3. Laden von Daten aus einer Datei
  172.   ----------------------------------
  173.      Wie sich aus den obigen Beispiel ersehen läßt, hat eine
  174.      Applikation (!) eine Datei zu laden, wenn Message_DataLoad
  175.      empfangen wird.
  176.      
  177.      Der übliche Weg, einem Programm eine derartige Nachricht
  178.      zukommen zu lassen, ist ein Icon aus einem Verzeichnisfenster
  179.      auf ein Fenster oder das Iconbar-Icon des Programms zu ziehen.
  180.      Folgendes passiert:
  181.  
  182.        1. Message_DataLoad <Kompl.PfadName> wird empfangen.
  183.        2. <Kompl.PfadName> laden.
  184.        3. Message_DataLoadAck <Kompl.PfadName> senden.
  185.        
  186.        => Zu beachten ist, daß in Schritt 2 die Datei nach dem
  187.           Einlesen nicht gelöscht werden darf. Es muß also
  188.           festgehalten werden, ob vorher Message_DataSave
  189.           empfangen wurde, was ein sicheres Anzeichen dafür ist,
  190.           daß es sich bei der 'Gegenstelle' ebenfalls um eine
  191.           Applikation handelt.
  192.  
  193.   4. Laden von Daten einer anderen Applikation
  194.   --------------------------------------------
  195.      Hier handelt es sich um Fall 2, nur von der Seite des
  196.      Empfängers aus gesehen. Ich fasse nochmal zusammen:
  197.  
  198.        1. Message_DataSave <DateiEndName> wird empfangen.
  199.        
  200.        2. Message_DataSaveAck <Wimp$Scrap> senden.
  201.        
  202.        3. Das andere Programm speichert in <Wimp$Scrap>.
  203.        
  204.        4. Message_DataLoad <Wimp$Scrap> wird empfangen.
  205.        
  206.        5. <Wimp$Scrap> laden und löschen.
  207.        
  208.        6. Message_DataLoadAck <Wimp$Scrap> senden.
  209.  
  210.        => In diesem Fall muß die temporäre Datei gelöscht
  211.           werden. Siehe Fall 3.
  212.           
  213.        => Schritt 5 darf erst ausgeführt werden, wenn auch
  214.           die Aufforderung mittels Message_DataLoad einge-
  215.           gangen ist (Schritt 4).
  216.  
  217.   5. Automatisches Laden von Daten aus Dateien.
  218.   ---------------------------------------------
  219.      Dieser Fall unterscheidet sich nicht großartig von Fall 3,
  220.      ist aber eines der Grundelemente des Desktops. Wie auch
  221.      unter anderen Betriebssystemen kann man Dateien 'öffnen',
  222.      'starten' bzw. anzeigen lassen, indem man einen Doppel-
  223.      klick über dem Icon der gewünschten Datei ausführt.
  224.      Folgendes passiert:
  225.  
  226.        1. Message_DataOpen <DateiEndName> wird empfangen.
  227.        
  228.        2. <DateiEndName> laden.
  229.        
  230.        3. Message_DataLoadAck <DateiEndName> senden.
  231.        
  232.        => Die Bedingung, ob eine Datei zu laden ist, ist deren
  233.           Dateityp, der in der Message übermittelt wird. !Edit
  234.           reagiert normalerweise auch nur auf Doppelklicks,
  235.           wenn sie über Text-Dateien stattfinden.
  236.           
  237.        => Antwortet keine Applikation auf Message_DataOpen, so
  238.           führt der Filer *Run <DateiEndName> aus, greift also
  239.           auf eventuell definierte Systemvariablen zurück. Ist
  240.           für den entsprechenden Dateityp nichts definiert,
  241.           wird die Fehlermeldung 'No run action specified for
  242.           this filetype' erzeugt.
  243.           
  244.        => Soll eine Datei aufgrund Message_DataOpen geladen
  245.           werden, so ist das vor dem nächsten Aufruf von
  246.           Wimp_Poll auch mit Message_DataLoadAck <DateiEndName>
  247.           zu bestätigen. Geschieht das nicht, dann hat der
  248.           Benutzer dummerweise zwei Exemplare des gleichen
  249.           Programms auf dem Desktop, die beide die gleiche
  250.           Datei geladen haben. Tritt dann noch der Fall auf,
  251.           daß die bereits geladene Applikation nicht genug
  252.           Speicher hat, um die Datei zu laden, wird die neu
  253.           gestarte Applikation ebenfalls nicht genug Speicher
  254.           zu Verfügung haben ... sprich: doppelte Fehlermeldung.
  255.  
  256.   6. Datenübertragung via RAM
  257.   ---------------------------
  258.      Es gibt eine Erweiterung des Data Transfer Protocol, um
  259.      die Übertragung von Daten zwischen zwei Applikationen zu
  260.      beschleunigen. Hierbei werden die zu transferrierenden
  261.      Daten nicht in einer temporären Datei zwischengelagert,
  262.      sondern via Wimp_Transferblock direkt zwischen den
  263.      Addressräumen der zwei beteiligten Programmen übertragen.
  264.      Das oben beschriebene Protokoll wird wie folgt erweitert:
  265.  
  266.        Übertragen von Daten zu einer anderen Applikation
  267.        -------------------------------------------------
  268.        1. A -> B: Message_DataSave <DateiEndName>
  269.        2. B -> A: Message_RAMFetch
  270.        3. A -> B: Message_RAMTransmit <data>
  271.        4. B -> A: Message_RAMFetch ...
  272.  
  273.        Die letzten beiden Schritte werden wiederholt, bis
  274.        alle Daten gesendet und empfangen wurden.
  275.  
  276.        Laden von Daten einer anderen Applikation
  277.        -----------------------------------------
  278.        1. B -> A: Message_DataSave <DateiEndName>
  279.        2. A -> B: Message_RAMFetch
  280.        3.      A: Wenn Schritt 2 von B nicht bestätigt wird,
  281.                   wird vorgegangen wie üblich:
  282.                   Message_DataSaveAck <Wimp$Scrap> usw ...
  283.                   ansonsten: B -> A: Message_RAMTransmit
  284.        4.      A: Daten empfangen und verarbeiten.
  285.        5. Solange der mittels Message_RAMTransmit proto-
  286.           kollierte Buffer voll ist:
  287.           A -> B: Message_RAMFetch
  288.                B: Wimp_TransferBlock
  289.           B -> A: Message_RAMTransmit
  290.  
  291.        => Wenn die erste Message_RAMFetch von der übertragenden
  292.          Applikation B nicht bestätigt wird (also in Form einer
  293.           User_Message_Acknowledge, Typ 19 zurück zum Absender
  294.           A gelangt), sollte die empfangende Applikation A das
  295.           übliche Verfahren via temporärer Datei verwenden.
  296.  
  297.        => Wenn eine der nachfolgenden Message_RAMFetch nicht
  298.           von B (mit Message_RAMTransmit) beantwortet werden,
  299.           sollte A den Empfang kommentarlos (d.h., ohne Fehler-
  300.           meldung) abbrechen.
  301.  
  302.        => Die Daten selbst werden von B mit Wimp_TransferBlock
  303.           übertragen. Die dazu benötigten Informationen, also
  304.           die Adresse und die Größe des Buffers werden von A
  305.           mittels Message_RAMFetch mitgeteilt.
  306.  
  307.        => Abbruchbedingung für den Übertragungsprozeß ist ein
  308.           nicht voller Buffer. Ist die Anzahl der insgesamt zu
  309.           übertragenden Bytes genau ein Mehrfaches der Größe
  310.           des Buffers, so ist ein abschließendes Paar von
  311.           Nachrichten zwischen den Applikationen zu senden,
  312.           bei denen 0 Bytes zu übertragen sind.
  313.  
  314.        => Aus den Beschreibungen im Programmers Reference Manual
  315.           geht leider nicht hervor, ob es erlaubt ist, die
  316.           Größe des Buffers während der Übertragung zu ver-
  317.           ändern. Hier gilt wieder: einige Programme reagieren
  318.           in dieser Hinsicht empfindlich. Man sollte also darauf
  319.           verzichten.
  320.